﻿using Nancy.Security;
using RinNote.Server.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RinNote.Server.Authentication
{
    class UserIdentity : IUserIdentity
    {
        public UserIdentity(string userName) :
            this(userName, new List<string>())
        {
        }
        public UserIdentity(string userName, IEnumerable<string> claims)
        {
            this.UserName = userName;
            this.Claims = claims;
        }

        public IEnumerable<string> Claims
        {
            get; private set;
        }

        public string UserName
        {
            get; private set;
        }
    }
    /// <summary>
    /// 包含生成token和校验token的静态方法
    /// </summary>
    public class UserMapper
    {
        private static LoginUsers manager = new LoginUsers();
        /// <summary>
        /// 根据token获取用户信息，检测用户是否有效
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static IUserIdentity GetUserFromAccessToken(string token)
        {
            return manager[token]?.identity;
        }
        /// <summary>
        /// 根据Token获取用户账户
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static Account GetUserAccountFromAccessToken(string token)
        {
            return manager[token]?.account;
        }
        /// <summary>
        ///  生成一个新的用户token,并缓存
        /// </summary>
        /// <param name="user"></param>
        /// <param name="expiryDate">过期日期</param>
        /// <returns></returns>
        public static string GenerateToken(Account user,DateTime expiryDate)
        {
            string token = Guid.NewGuid().ToString();
            //token有效期
            //manager.Set(token, new UserIdentity(userName), 60 * 24);
            manager.AddLoginUser(token, user, expiryDate);
            return token;
        }
        /// <summary>
        /// 移除一个token
        /// </summary>
        /// <param name="user"></param>
        public static void RemoveToken(string token)
        {
            manager.RemoveLoginUserByToken(token);
        }
    }
    /// <summary>
    /// 已验证用户列表对象
    /// </summary>
    public class LoginUsers
    {
        private static List<LoginUser> loginUserList = new List<LoginUser>();
        /// <summary>
        /// 根据Token获得已验证用户对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public LoginUser this[string name]
        {
            get
            {
                var _user = loginUserList.Where(i => i.Token == name).FirstOrDefault();
                if (_user != null)
                {
                    if (_user.ExpiryDate < DateTime.Now)
                    {
                        loginUserList.Remove(_user);
                        return null;
                    }
                }
                return _user;
            }
        }
        /// <summary>
        /// 根据用户名获得已验证用户对象
        /// </summary>
        /// <returns></returns>
        public LoginUser GerLoginUserByUsername(string username)
        {
            return loginUserList.Where(i => i.identity.UserName == username).FirstOrDefault();
        }
        /// <summary>
        /// 根据用户名移除已验证用户对象
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public bool RemoveLoginUserByUsername(string username)
        {
            var _user = loginUserList.Where(i => i.account.UserName == username).FirstOrDefault();
            if (_user == null)
            {
                return false;
            }
            else
            {
                return loginUserList.Remove(_user);
            }
        }
        /// <summary>
        /// 根据Token移除已验证用户对象
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool RemoveLoginUserByToken(string token)
        {
            var _user = this[token];
            if (_user == null) return false;
            return loginUserList.Remove(_user);
        }
        /// <summary>
        /// 添加一个登录用户
        /// </summary>
        public void AddLoginUser(string token,Account account,DateTime expiryDate)
        {
            if (this.GerLoginUserByUsername(account.UserName)== null)
            {
                loginUserList.Add(new LoginUser() {
                    Token=token,
                    identity=new UserIdentity(account.UserName,new string[] {account.Role.ToString()}),
                    account=account,
                    ExpiryDate= expiryDate
                });
            }
        }
    }
    public class LoginUser
    {
        public IUserIdentity identity { get; set; }
        public string Token { get; set; }
        public Account account { get; set; }
        public DateTime? ExpiryDate { get; set; }
    }
}
